//
//  MySocket.m
//  client100
//
//  Created by 孙晓晔 on 2017/5/18.
//  Copyright © 2017年 孙晓晔. All rights reserved.
//

#import "MySocket.h"

#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

@interface MySocket()

@property(nonatomic,assign) int serverSocket; // 通讯套接字
@property(nonatomic,strong) NSMutableArray *msg; // 消息列表

@end

@implementation MySocket

-(instancetype)initWithHostPort:(NSString*)host port:(int)port {
    self = [super init];
    
    if (self) {
        self.host = host;
        self.port = port;
    }
    
    return self;
}

// 懒加载
-(NSArray *)userList {
    if (_userList == nil) {
        _userList = [NSArray array];
    }
    
    return _userList;
}

-(NSMutableArray *)msg {
    if (_msg == nil) {
        _msg = [NSMutableArray array];
    }
    
    return _msg;
}

// 创建socket并连接
-(void)createSockect {
    int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        NSLog(@"创建socket失败", nil);
        return;
    }
    
    NSLog(@"创建socket成功", nil);
    
    struct sockaddr_in server_addr;
    
    server_addr.sin_len = sizeof(struct sockaddr_in);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(self.port);
    server_addr.sin_addr.s_addr = inet_addr([self.host cStringUsingEncoding:NSUTF8StringEncoding]);
    bzero(&(server_addr.sin_zero), 8);
    
    int ret = connect(serverSocket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
    if (ret == -1) {
        NSLog(@"连接失败", nil);
        return;
    }
    
    NSLog(@"连接成功", nil);
    
    [self recv:serverSocket];
}

// 接受数据
-(void)recv:(int)serverSocket {
    self.serverSocket = serverSocket;
    
    self.isConnected = TRUE;
    
    [self login];
    
    while(1) {
        char buf[1024] = {0};
        ssize_t ret = recv(serverSocket, buf, 1024, 0);
        if (ret > 0) {
            
            printf("recv:%s\n", buf);
            
            NSString *jsonString = [NSString stringWithCString:buf encoding:NSUTF8StringEncoding];
            
            NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
            
            NSError *err;
            
            id object = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
            
            if (err) {
                NSLog(@"数据包解析出错");
                break;
            }
            
            [self parse:object];
            
        } else if (ret == -1) {
            [self logout];
            break;
        }
    }
}

// 协议解析
-(void)parse:(id)object {
    
    if ([object isKindOfClass:[NSArray class]]) {
        self.userList = object;
        
    } else if ([object isKindOfClass:[NSDictionary class]]) {
        [self message:object];
    }

}

-(void)message:(NSDictionary*)dic {
    NSString *type = [dic valueForKey:@"type"];
    
//    NSString *from = [dic valueForKey:@"from"];
//     NSString *to = [dic valueForKey:@"to"];
    
    NSLog(@"%@", type);
    
    if ([type isEqualToString:@"chat"]) {
        
        [self.msg addObject:dic];
        if (self.msg.count > 20) {
            [self.msg removeObjectAtIndex:0];
        }
    }
}

-(NSString*)msgList {
    NSString *ret = @"";
    
    for (int i = self.msg.count - 1; i >=0; i--) {
        NSDictionary *dic = self.msg[i];
        
        NSString *from = [dic objectForKey:@"from"];
        NSString *to = [dic objectForKey:@"to"];
        NSString *body = [dic objectForKey:@"body"];
        
        ret = [ret stringByAppendingFormat:@"%@ %@ %@\n", from, to, body];
    }
    
    return ret;
}

// 写数据
-(ssize_t)writeData:(NSDictionary*)dic {
    NSError *parseError = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError];
    
    NSString *str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    const char *buf = [str cStringUsingEncoding:NSUTF8StringEncoding];
    
    return send(self.serverSocket, buf, 1024, 0);
}

// 登入
-(void)login {
    
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    
    [dic setValue:@"login" forKey:@"type"];
    [dic setValue:self.nickname forKey:@"nickname"];
    [dic setValue:@"all" forKey:@"to"];
    [dic setValue:@"" forKey:@"body"];
    
    ssize_t ret = [self writeData:dic];
    
    if (ret > 0) {
        NSLog(@"登录成功", nil);
    }
}

// 退出
-(void)logout {
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    
    [dic setValue:@"logout" forKey:@"type"];
    [dic setValue:self.nickname forKey:@"nickname"];
    [dic setValue:@"all" forKey:@"to"];
    [dic setValue:@"" forKey:@"body"];
    
    ssize_t ret = [self writeData:dic];
    if (ret > 0) {
        NSLog(@"退出", nil);
    }
}

// 聊天
-(void)chat:(NSString*)to body:(NSString*)body {
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    
    [dic setValue:@"chat" forKey:@"type"];
    [dic setValue:self.nickname forKey:@"nickname"];
    [dic setValue:to forKey:@"to"];
    [dic setValue:body forKey:@"body"];
    
    [self.msg addObject:dic];
    
    ssize_t ret = [self writeData:dic];
    if (ret > 0) {
        NSLog(@"发送成功", nil);
    }
}

// 用户列表
-(NSString*)stringUserList {
    
    NSString *ret = @"";
    
    for(NSDictionary *key in self.userList) {
        NSString *from = [key objectForKey:@"id"];
        NSString *nickname = [key objectForKey:@"name"];
        
        ret = [ret stringByAppendingFormat:@"%@ = %@\n", from, nickname];
    }
    
    return ret;
}

// 断开
-(void)close {
    [self logout];
    
    self.isConnected = FALSE;
    
    close(self.serverSocket);
}

@end
